# -*- coding:utf-8 -*-

"""
描述：
Created on 2016/11/26
@author: Line
"""

import sys

reload(sys)
sys.setdefaultencoding('utf-8')

import os
import json

from PIL import Image
from xml.etree import ElementTree

import logging  # 引入logging模块

logging.basicConfig(level=logging.DEBUG)  # 设置日志级别
logger = logging.getLogger(__file__)


def tree_to_dict(tree):
    d = {}
    for index, item in enumerate(tree):
        if item.tag == 'key':
            if tree[index + 1].tag == 'string':
                d[item.text] = tree[index + 1].text
            elif tree[index + 1].tag == 'integer':
                d[item.text] = int(tree[index + 1].text)
            elif tree[index + 1].tag == 'real':
                d[item.text] = int(tree[index + 1].text)
            elif tree[index + 1].tag == 'true':
                d[item.text] = True
            elif tree[index + 1].tag == 'false':
                d[item.text] = False
            elif tree[index + 1].tag == 'dict':
                d[item.text] = tree_to_dict(tree[index + 1])
    return d


def to_list(x):
    l = x.replace('{', '').replace('}', '').split(',')
    t = []
    for i in l:
        t.append(int(float(i)))
    return t


def gen_png_from_plist(plist_filename):
    try:
        file_path = os.path.dirname(plist_filename)
        # logger.info(u"当前目录[%s], 开始处理文件[%s]" % (file_path, plist_filename))
        root = ElementTree.fromstring(open(plist_filename, 'r').read())
        plist_dict = tree_to_dict(root[0])
        if not (plist_dict.get('frames') and plist_dict.get('metadata')):
            logger.error(u"当前目录[%s], 开始处理文件[%s]错误，数据中没有frames或metadata, keys[%s]" % (file_path, plist_filename, plist_dict.keys()))
            return

        metadataItem = plist_dict.get('metadata')
        realTextureFileName = metadataItem.get("realTextureFileName")
        pngFilename = os.path.join(file_path, realTextureFileName).replace("\\", "/")
        if not os.path.exists(pngFilename):
            logger.error(u"当前目录[%s], 开始处理文件[%s]错误，纹理文件[%s]不存在" % (file_path, plist_filename, pngFilename))
            return

        subDirName = os.path.basename(plist_filename).split(".")[0]
        formatVersion = int(metadataItem.get("format"))

        big_image = Image.open(pngFilename)
        # textureItem = plist_dict.get('texture')
        # textureWidth = textureItem.get("width")
        # textureHeight = textureItem.get("height")
        for k, smallItem in plist_dict['frames'].items():
            try:
                # logger.info("k:%s,smallItem:%s" % (k, smallItem))
                if formatVersion == 2:
                    sourceColorRect = to_list(smallItem.get("sourceColorRect"))
                    frameBox = to_list(smallItem.get('frame'))
                    sourceSize = to_list(smallItem.get("sourceSize"))
                    offset = to_list(smallItem.get("offset"))
                    rotated = smallItem.get('rotated', False)  # 是否旋转

                    # 大图上的需要剪切的区域
                    clipX = int(frameBox[0])
                    clipY = int(frameBox[1])
                    width = int(frameBox[2])
                    height = int(frameBox[3])
                elif formatVersion == 0:
                    sourceSize = (smallItem.get("width"), smallItem.get("height"))
                    offset = (smallItem.get("offsetX"), smallItem.get("offsetY"))
                    rotated = smallItem.get('rotated', False)  # 是否旋转
                    # 大图上的需要剪切的区域
                    clipX = smallItem.get("x")
                    clipY = smallItem.get("y")
                    width = smallItem.get("width")
                    height = smallItem.get("height")
                else:
                    logger.error(u"当前目录[%s], 开始处理文件[%s]错误，不能够识别文件内容格式 formatVersion[%s]" % (file_path, plist_filename, formatVersion))
                    continue

                resultImg = Image.new('RGBA', sourceSize, (0, 0, 0, 0))
                if rotated:
                    clipBox = (clipX, clipY, clipX + height, clipY + width)
                    clipBoxImg = big_image.crop(clipBox)
                    clipBoxImg = clipBoxImg.rotate(90, expand=True)
                    result_box = (abs(offset[0]), abs(offset[1]), width, height)
                    resultImg.paste(clipBoxImg, tuple(result_box), mask=0)
                else:
                    clipBox = (clipX, clipY, clipX + width, clipY + height)
                    clipBoxImg = big_image.crop(clipBox)
                    result_box = (abs(offset[0]), abs(offset[1]), width + abs(offset[0]), height + abs(offset[1]))
                    resultImg.paste(clipBoxImg, tuple(result_box), mask=0)

                # outfile = file_path + '\\' + k
                # outfile = outfile.replace("/", "\\")
                # lastPath = os.path.dirname(outfile)
                outfile = os.path.join(file_path, "%s/%s" % (subDirName, k,)).replace("\\", "/")
                lastPath = os.path.dirname(outfile)
                if not os.path.exists(lastPath):
                    os.makedirs(lastPath)
                # logger.info(u"生成小图片[%s]" % (outfile,))
                if resultImg:
                    resultImg.save(outfile)
            except:
                logger.exception(u"处理文件[%s]生成小图[%s]异常" % (plist_filename, k))
    except:
        logger.exception(u"处理文件[%s]异常" % (plist_filename,))


def unpack_a_file(filename):
    # logger.info(u"处理文件[%s]" % (filename,))
    if not os.path.exists(filename):
        logger.warn(u"处理文件[%s]不存在" % (filename,))
    else:
        gen_png_from_plist(filename)
    pass


def unpack_dir_file(path):
    logger.info(u"处理目录[%s]" % (path,))
    for dirpath, dirs, files in os.walk(path):
        for file in files:
            abs_path = os.path.join(dirpath, file)
            postfix = os.path.splitext(abs_path)[1]
            if postfix == ".plist":
                unpack_a_file(abs_path)


if __name__ == '__main__':
    # filename = sys.argv[1]
    unpack_dir_file(u"G:\\房卡游戏包\\csmj")
